package com.pureut.production.service.impl;

import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pureut.common.core.web.domain.AjaxResult;
import com.pureut.common.datascope.annotation.DataScope;
import com.pureut.common.security.utils.DictUtils;
import com.pureut.common.security.utils.SecurityUtils;
import com.pureut.equipment.api.FeignEquipmentService;
import com.pureut.production.domain.ProcessCardLog;
import com.pureut.production.domain.ProcessPropertyLog;
import com.pureut.production.domain.ProcessSheet;
import com.pureut.production.domain.ProcessTempleteDrviceLog;
import com.pureut.production.domain.dto.*;
import com.pureut.production.domain.dto.equipment.GetDeviceInfoDto;
import com.pureut.production.domain.vo.ProcessCardLogVo;
import com.pureut.production.mapper.ProcessCardLogMapper;
import com.pureut.production.mapper.ProcessPropertyLogMapper;
import com.pureut.production.mapper.ProcessSheetMapper;
import com.pureut.production.mapper.ProcessTempleteDrviceLogMapper;
import com.pureut.production.service.ProcessCardLogService;
import com.pureut.production.service.ProcessPropertyLogService;
import com.pureut.production.service.ProcessSheetService;
import com.pureut.production.service.ProcessTempleteDrviceLogService;
import com.pureut.system.api.domain.SysDictData;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Author: YSL
 * @Date: 2023-02-16 14:42:27
 * @Desc: 工艺卡日志
 */
@Service("processCardLogService")
public class ProcessCardLogServiceImpl extends ServiceImpl<ProcessCardLogMapper, ProcessCardLog> implements ProcessCardLogService {

    /**
     * 工艺卡日志Dao
     */
    @Resource
    private ProcessCardLogMapper processCardLogMapper;

    /**
     * 工艺卡Service
     */
    @Resource
    private ProcessSheetService processSheetService;

    /**
     * 工艺卡mapper
     */
    @Resource
    private ProcessSheetMapper processSheetMapper;

    /**
     * 工艺卡关联设备mapper
     */
    @Resource
    private ProcessTempleteDrviceLogMapper processTempleteDrviceLogMapper;

    /**
     * 工艺卡设备Service
     */
    @Resource
    private ProcessTempleteDrviceLogService processTempleteDrviceLogService;

    /**
     * 工艺卡设备属性
     */
    @Resource
    private ProcessPropertyLogService processPropertyLogService;

    /**
     * 工艺卡设备属性mapper
     */
    @Resource
    private ProcessPropertyLogMapper processPropertyLogMapper;

    /**
     * 设备Feign
     */
    @Resource
    FeignEquipmentService feignEquipmentService;


    /**
     * 查询工艺卡日志列表
     *
     * @param processCardLogVo
     * @return
     */
    @Override
    @DataScope(deptAlias = "t1")
    public List<ProcessCardLogDto> selectProcessCardLogList(ProcessCardLogVo processCardLogVo) {
        return processCardLogMapper.selectProcessCardLogList(processCardLogVo);
    }

    /**
     * 新增工艺卡日志
     *
     * @param processCardLogVo
     * @return
     */
    @Override
    public boolean insertProcessCardLog(ProcessCardLogVo processCardLogVo) {
        ProcessCardLog processCardLog = new ProcessCardLog();
        BeanUtils.copyProperties(processCardLogVo, processCardLog);
        processCardLog.setPmMoNumber(processCardLogVo.getPmMoNumber());
        processCardLog.setProcessCardCoding(processCardLogVo.getProcessCardCoding());
        processCardLog.setProcessCardName(processCardLogVo.getProcessCardName());
        processCardLog.setMaterialCode(processCardLogVo.getMaterialCode());
        processCardLog.setMaterialName(processCardLogVo.getMaterialName());
        processCardLog.setProductionLine(processCardLogVo.getProductionLine());
        processCardLog.setFlowName(processCardLogVo.getFlowName());
        processCardLog.setCreateUser(SecurityUtils.getLoginUser().getUsername());
        processCardLog.setCreateTime(new Date());
        processCardLog.setDeptId(SecurityUtils.getDeptId());
        return save(processCardLog);
    }

    /**
     * 查看工艺卡日志
     *
     * @param id
     * @return
     */
    @Override
    public PublicProcessDto view(Long id) {

        ProcessCardLog byId = getById(id);

        ProcessSheet processSheet = processSheetMapper.selectOne(new QueryWrapper<ProcessSheet>().lambda().eq(ProcessSheet::getProcessCardCoding, byId.getProcessCardCoding()));


        //通过id查出工艺编码，工艺卡名称，工艺流程，生产线别，生产阶别，物料编码，物料名称，物料规格
        ProcessSheetDto processSheetDto = processSheetMapper.getProcessSheet(processSheet.getId());

        PublicProcessDto publicProcessDto = new PublicProcessDto();
        List<SysDictData> statusArray = DictUtils.getDictCache("quality_production_level");
        Map<String, String> statusMap = statusArray.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));
        //生产阶别
        publicProcessDto.setProductionLevel(statusMap.get(processSheetDto.getProductionLevel()));
        publicProcessDto.setProcessCardId(id);
        //生产线别
        publicProcessDto.setProductionLine(byId.getProductionLine());

        publicProcessDto.setProcessCardName(processSheetDto.getMaterialName());
        publicProcessDto.setProcessCardCoding(processSheetDto.getProcessCardCoding());
        publicProcessDto.setMaterialCode(processSheetDto.getMaterialCode());
        publicProcessDto.setMaterialName(processSheetDto.getMaterialName());
        publicProcessDto.setMaterialSpec(processSheetDto.getMaterialSpec());
        publicProcessDto.setFlowName(processSheetDto.getFlowName());
        publicProcessDto.setFlowId(processSheetDto.getFlowId());
        //获取设备+属性集合
        List<ProcessCardTempleteDto> list = new ArrayList<>();

        //获取设备编码到list集合中
        List<ProcessTempleteDrviceLog> processTempleteDrviceList = processTempleteDrviceLogMapper.selectList(new QueryWrapper<ProcessTempleteDrviceLog>().lambda().eq(ProcessTempleteDrviceLog::getProcessTempleteId, id));
        for (ProcessTempleteDrviceLog processTempleteDrvice : processTempleteDrviceList) {
            ProcessCardTempleteDto processCardTempleteDto = new ProcessCardTempleteDto();
            //添加设备编码
            processCardTempleteDto.setDeviceCode(processTempleteDrvice.getDrviceCode());

            AjaxResult deviceInfo = feignEquipmentService.getDeviceInfo(processTempleteDrvice.getDrviceCode());
            GetDeviceInfoDto getDeviceInfoDto = JSON.parseObject(JSON.toJSONString(deviceInfo.get("data")), GetDeviceInfoDto.class);
            if (getDeviceInfoDto.getDeviceType() != null) {
                processCardTempleteDto.setDeviceName(getDeviceInfoDto.getDeviceName());
                processCardTempleteDto.setDeviceType(getDeviceInfoDto.getDeviceType());
            }
            //获取设备属性信息
            List<ProcessPropertyDto> processList = new ArrayList<>();

            //查询当前设备编码对应的属性和值
            List<ProcessPropertyLog> processPropertyList = processPropertyLogMapper.selectList(new QueryWrapper<ProcessPropertyLog>().lambda().eq(ProcessPropertyLog::getTempleteDrviceId, processTempleteDrvice.getId()));
            for (ProcessPropertyLog processPropertyLog : processPropertyList) {
                ProcessPropertyDto processPropertyDto = new ProcessPropertyDto();
                processPropertyDto.setDeviceAddedit(processPropertyLog.getProperty());
                processPropertyDto.setValue(processPropertyLog.getValue());

                processList.add(processPropertyDto);
            }
            processCardTempleteDto.setProcessList(processList);
            list.add(processCardTempleteDto);
        }

        publicProcessDto.setList(list);

        return publicProcessDto;
    }

    /**
     * 导出
     *
     * @param processCardLogVo
     * @return
     */
    @Override
    public XSSFWorkbook outputExcl(ProcessCardLogVo processCardLogVo) {
        List<ProcessCardLogDto> processCardLogDtos;

        List<SysDictData> statusArray = DictUtils.getDictCache("quality_production_level");
        Map<String, String> statusMap = statusArray.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));

        if (processCardLogVo.getIdStr() == null) {
            processCardLogDtos = processCardLogMapper.selectProcessCardLogListOut(processCardLogVo);
        } else {
            List<String> idList = Arrays.asList(processCardLogVo.getIdStr().split(","));
            processCardLogDtos = processCardLogMapper.getDataByIdStr(idList);
        }
        //创建excl表格
        XSSFWorkbook sheets = new XSSFWorkbook();
        //设置第一列表头列表
        LinkedList<String> title = new LinkedList<>();
        title.add("工艺卡编码");
        title.add("工艺卡名称");
        title.add("制令单号");
        title.add("生产线别");
        title.add("生产阶别");
        title.add("物料编码");
        title.add("物料名称");
        title.add("物料规格");
        title.add("工艺流程");
        int i = 0;
        for (ProcessCardLogDto entity : processCardLogDtos) {
            i++;
            //创建sheet表
            XSSFSheet sheet = sheets.createSheet("工艺卡" + i);
            //创建当前sheet的第一行
            Row row = sheet.createRow(0);
            //第二行开始插入第一行表头数据
            Row rowTwo = sheet.createRow(1);
            //插入第一行表头
            for (int a = 0; a < title.size(); a++) {
                row.createCell(a).setCellValue(title.get(a));
            }
            //插入第一个表头对应数据
            rowTwo.createCell(0).setCellValue(entity.getProcessCardCoding());
            rowTwo.createCell(1).setCellValue(entity.getProcessCardName());
            rowTwo.createCell(2).setCellValue(entity.getPmMoNumber());
            rowTwo.createCell(3).setCellValue(entity.getProductionLine());
            rowTwo.createCell(4).setCellValue(statusMap.get(entity.getProductionLevel()));
            rowTwo.createCell(5).setCellValue(entity.getMaterialCode());
            rowTwo.createCell(6).setCellValue(entity.getMaterialName());
            rowTwo.createCell(7).setCellValue(entity.getMaterialSpec());
            rowTwo.createCell(8).setCellValue(entity.getFlowName());
            //获取当前工艺卡日志关联的设备
            List<ProcessTempleteDrviceLogDto> processTempleteDrviceList = processTempleteDrviceLogMapper.getProcessTempleteDrviceList(entity.getId());
            int b = 3;
            int c = 4;
            for (ProcessTempleteDrviceLogDto drivce : processTempleteDrviceList) {
                //获取第二表头
                LinkedList<String> titleTwo = new LinkedList<>();
                titleTwo.add("设备编码");
                titleTwo.add("设备名称");
                titleTwo.add("设备类型");
                //获取当前工艺卡日志对应的属性
                List<ProcessPropertyDto> processPropertyLogList = processPropertyLogMapper.getProcessPropertyLogList(drivce.getId());
                for (ProcessPropertyDto processPropertyDto : processPropertyLogList) {
                    titleTwo.add(processPropertyDto.getDeviceAddedit());
                }
                //添加下方表头
                Row rowThree = sheet.createRow(b);
                for (int a = 0; a < titleTwo.size(); a++) {
                    rowThree.createCell(a).setCellValue(titleTwo.get(a));
                }
                //获取设备数据
                AjaxResult deviceInfo = feignEquipmentService.getDeviceInfo(drivce.getDrviceCode());
                GetDeviceInfoDto getDeviceInfoDto = JSON.parseObject(JSON.toJSONString(deviceInfo.get("data")), GetDeviceInfoDto.class);
                Row dataRow = sheet.createRow(c);
                dataRow.createCell(0).setCellValue(drivce.getDrviceCode());
                dataRow.createCell(1).setCellValue(getDeviceInfoDto.getDeviceName());
                dataRow.createCell(2).setCellValue(getDeviceInfoDto.getDeviceType());
                int num = 3;
                for (int k = 0; k < num; k++) {
                    dataRow.createCell(num).setCellValue(processPropertyLogList.get(k).getValue());
                    num++;
                    if (num == titleTwo.size()) {
                        break;
                    }
                }
                c += 2;
                b += 2;
            }
        }


        return sheets;
    }
}
